package org.farec.tcc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.farec.tcc.modelo.Grupo;

public class GrupoDAO {
	
	private Connection connection;
		
	public GrupoDAO(Connection connection)
	{
		this.connection = connection;
	}

	public void adiciona(Grupo grupo)
	{
		final String sql = "INSERT INTO grupo(nome,idempresa) VALUES(?,?)";
		String sql2= "INSERT INTO permissaodogrupo(idgrupo, modulo, permissao, item) VALUES(?,?,?,?)";
		
		try
		{
			//Prepara o statement para insercao
			PreparedStatement stmt = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
			PreparedStatement stmt2 = connection.prepareStatement(sql2); 
			
			//seta os dados
			stmt.setString(1, grupo.getNome());
			stmt.setInt(2, grupo.getCodEmpresa());
			stmt.execute();
			
			ResultSet rs = stmt.getGeneratedKeys();
			
			if(rs.next())
			{
				int idGrupo = rs.getInt("id");
				
				Map<String,List<String>> permissoesMap = grupo.getModuloPermissaoMap();
				for( Entry<String,List<String>> entry : permissoesMap.entrySet() )
				{
					for( String acao : entry.getValue() )
					{
						stmt2.setInt ( 1 , idGrupo );
						stmt2.setString ( 2 , entry.getKey() );
						stmt2.setBoolean( 3 , true );
						stmt2.setString ( 4 , acao );
						stmt2.execute();
					}
				}

				stmt.close();
				stmt2.close();	
			}
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		
	}
	
	public List<Grupo> getLista(int codEmpresa, String ordem)
	{
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("SELECT * from grupo WHERE idempresa=? or nome=? order by "+ordem);
			stmt.setInt(1,codEmpresa);
			stmt.setString(2, "ADMINISTRADORES");
			
			ResultSet rs = stmt.executeQuery();
			List<Grupo> grupos = new ArrayList<Grupo>();
			
			while(rs.next())
			{
				//Criando um nova instancia
				Grupo grupo = new Grupo();
				grupo.setCodigo(rs.getInt("id"));
				grupo.setNome(rs.getString("nome"));
									
				//Adicionando objeto a lista
				grupos.add(grupo);
			}
			
			rs.close();
			stmt.close();
			return grupos;
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public void altera(Grupo grupo)
	{
		String sql = "UPDATE grupo set nome=? where idempresa=? and id=?",
		sql2 = "DELETE from permissaodogrupo where idgrupo=?",
		sql3 = "INSERT INTO permissaodogrupo(idgrupo,modulo,permissao,item) VALUES(?,?,?,?)";
		
			try
			{
				
				System.out.println("CodGrupo: "+grupo.getCodigo());
				//Prepara o statement para insercao
				PreparedStatement stmt = connection.prepareStatement(sql);
				PreparedStatement stmt2 = connection.prepareStatement(sql2); 
				PreparedStatement stmt3 = connection.prepareStatement(sql3);
				
				//seta os dados
				stmt.setString(1, grupo.getNome());
				stmt.setInt(2, grupo.getCodEmpresa());
				stmt.setInt(3, grupo.getCodigo());
				stmt.execute();
		
				stmt2.setInt(1, grupo.getCodigo());
				stmt2.execute();
				
				Map<String,List<String>> permissoesMap = grupo.getModuloPermissaoMap();
				for( Entry<String,List<String>> entry : permissoesMap.entrySet() )
				{
					for( String acao : entry.getValue() )
					{
						stmt3.setInt ( 1 , grupo.getCodigo() );
						stmt3.setString ( 2 , entry.getKey() );
						stmt3.setBoolean( 3 , true );
						stmt3.setString ( 4 , acao );
						stmt3.execute();
					}
				}
				
				stmt.close();
				stmt2.close();
			
			}
			catch(SQLException e)
			{
				throw new RuntimeException(e);
			}
	}
	
	public void remove(Grupo grupo)

	{
		try
		{
			String sql = "DELETE from grupo where id=? and nome != ? and idempresa=?;";
	
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			stmt.setInt(1, grupo.getCodigo());
			stmt.setString(2,"ADMINISTRADORES");
			stmt.setInt(3, grupo.getCodEmpresa());
			
			stmt.execute();

			stmt.close();
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public Grupo buscaDados(int codEmpresa, String nome)
	{
		try
		{
			
			String sql = "SELECT id, nome from grupo where nome ILIKE ? and (idempresa=? or idempresa IS NULL);"; 
		
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			stmt.setString(1, nome);
			stmt.setInt(2, codEmpresa);
			
			ResultSet rs = stmt.executeQuery();
	
			//List<Grupo> grupos = new ArrayList<Grupo>();
			Grupo grupo = new Grupo();
			if( rs.next() )
			{
				String sql2 = "SELECT modulo, permissao, item from permissaodogrupo where idgrupo=? order by modulo;"; 
				PreparedStatement stmt2 = this.connection.prepareStatement(sql2);
				stmt2.setInt(1, rs.getInt("id"));
				ResultSet rs2 = stmt2.executeQuery();
				grupo = convertTo( rs , rs2 );
			}
			
			rs.close();
			stmt.close();
			return grupo;
			
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		
	}

	public Grupo getGrupo(Grupo grupo)
	{
		ResultSet rs;
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("select nome from grupo where nome ILIKE ? and idempresa=?");
			stmt.setString(1, grupo.getNome());
			stmt.setInt(2, grupo.getCodEmpresa());
			
			rs=stmt.executeQuery();
			
			if(rs.next())
			{
				grupo.setAlerta(true);
			}
			
			else
			{
				grupo.setAlerta(false);
			}
			stmt.close();
			rs.close();
		
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		return grupo;
		
	}

	public Grupo getGrupoUp(Grupo grupo)
	{
		ResultSet rs;
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("select nome from grupo where nome ILIKE ? and idempresa=? and id !=?");
			stmt.setString(1, grupo.getNome());
			stmt.setInt(2, grupo.getCodEmpresa());
			stmt.setInt(3, grupo.getCodigo());
			rs=stmt.executeQuery();
			
			if(rs.next())
			{
				grupo.setAlerta(true);
			}
			
			else
			{
				grupo.setAlerta(false);
			}
			stmt.close();
			rs.close();
		
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		return grupo; 
		
	}
	
	public Grupo getGrupoPorID(int codGrupo, int codEmpresa)
	{
		ResultSet rs;
		Grupo grupo = new Grupo();
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("select nome from grupo where id=? and (idempresa=? or idempresa IS NULL)");
			stmt.setInt(1, codGrupo);
			stmt.setInt(2, codEmpresa);
			
			rs=stmt.executeQuery();
			
			if(rs.next())
			{
				grupo.setNome(rs.getString("nome"));
			}
			
			stmt.close();
			rs.close();		
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		return grupo;
	}
	
	private Grupo convertTo( ResultSet rs , ResultSet rs2 ) throws SQLException
	{
		Grupo grupo = new Grupo();
		
		//Criando um nova instancia
		grupo.setCodigo( rs.getInt("id")      );
		grupo.setNome  ( rs.getString("nome") );
				
		List<String> l = new ArrayList<String>();
		
		while( rs2.next() )
		{
			String acao   = rs2.getString( "item" );
			String modulo = rs2.getString( "modulo" );
			
			if( !grupo.getModuloPermissaoMap().containsKey( modulo ) )	
			{
				grupo.getModuloPermissaoMap().put( modulo , new ArrayList<String>() );
			}
			
			grupo.getModuloPermissaoMap().get( modulo ).add( acao );
		}
		
		return grupo;
	}
}

